<template>
  <button
    :class="buttonClass"
    :disabled="disabled || loading"
    :type="htmlType"
    @click="handleClick"
  >
    <span v-if="loading" class="vt-button__loading">
      <svg class="vt-button__loading-icon" viewBox="0 0 24 24">
        <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none" opacity="0.25"/>
        <path d="M12 2 A 10 10 0 0 1 22 12" stroke="currentColor" stroke-width="2" fill="none">
          <animateTransform
            attributeName="transform"
            type="rotate"
            values="0 12 12;360 12 12"
            dur="1s"
            repeatCount="indefinite"
          />
        </path>
      </svg>
    </span>
    <span class="vt-button__content">
      <slot></slot>
    </span>
  </button>
</template>

<script setup lang="ts">
import { computed, useAttrs } from 'vue'
import type { ButtonProps, ButtonEmits } from './types'

const props = withDefaults(defineProps<ButtonProps>(), {
  type: 'primary',
  size: 'medium',
  disabled: false,
  loading: false,
  htmlType: 'button',
  block: false,
  round: false,
  circle: false
})

const emit = defineEmits<ButtonEmits>()
const attrs = useAttrs()

const buttonClass = computed(() => {
  return [
    'vt-button',
    `vt-button--${props.type}`,
    `vt-button--${props.size}`,
    {
      'vt-button--disabled': props.disabled,
      'vt-button--loading': props.loading,
      'vt-button--block': props.block,
      'vt-button--round': props.round,
      'vt-button--circle': props.circle,
    },
    attrs.class
  ]
})

const handleClick = (event: MouseEvent) => {
  if (props.disabled || props.loading) {
    return
  }
  emit('click', event)
}
</script>

<style scoped>
.vt-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  padding: 8px 16px;
  border: 1px solid transparent;
  border-radius: 4px;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.5;
  cursor: pointer;
  transition: all 0.2s ease-in-out;
  user-select: none;
  white-space: nowrap;
  box-sizing: border-box;
}

.vt-button:focus {
  outline: none;
}

/* 类型样式 */
.vt-button--primary {
  background-color: #409eff;
  border-color: #409eff;
  color: #ffffff;
}

.vt-button--primary:hover:not(.vt-button--disabled) {
  background-color: #66b1ff;
  border-color: #66b1ff;
}

.vt-button--secondary {
  background-color: #ffffff;
  border-color: #dcdfe6;
  color: #606266;
}

.vt-button--secondary:hover:not(.vt-button--disabled) {
  background-color: #ecf5ff;
  border-color: #409eff;
  color: #409eff;
}

.vt-button--danger {
  background-color: #f56c6c;
  border-color: #f56c6c;
  color: #ffffff;
}

.vt-button--danger:hover:not(.vt-button--disabled) {
  background-color: #f78989;
  border-color: #f78989;
}

.vt-button--text {
  background-color: transparent;
  border-color: transparent;
  color: #409eff;
  padding: 8px 4px;
}

.vt-button--text:hover:not(.vt-button--disabled) {
  background-color: #ecf5ff;
}

/* 尺寸样式 */
.vt-button--small {
  padding: 6px 12px;
  font-size: 12px;
  height: 28px;
}

.vt-button--medium {
  padding: 8px 16px;
  font-size: 14px;
  height: 36px;
}

.vt-button--large {
  padding: 10px 20px;
  font-size: 16px;
  height: 44px;
}

/* 状态样式 */
.vt-button--disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.vt-button--loading {
  cursor: not-allowed;
}

.vt-button--block {
  display: flex;
  width: 100%;
}

.vt-button--round {
  border-radius: 20px;
}

.vt-button--circle {
  border-radius: 50%;
  padding: 8px;
  width: 36px;
  height: 36px;
}

.vt-button--circle.vt-button--small {
  width: 28px;
  height: 28px;
  padding: 6px;
}

.vt-button--circle.vt-button--large {
  width: 44px;
  height: 44px;
  padding: 10px;
}

/* 加载状态 */
.vt-button__loading {
  display: inline-flex;
  align-items: center;
  margin-right: 6px;
}

.vt-button__loading-icon {
  width: 14px;
  height: 14px;
}

.vt-button__content {
  display: inline-flex;
  align-items: center;
}

.vt-button--loading .vt-button__content {
  opacity: 0.7;
}
</style>